package com.danger.dy.common.lang.httpclient;

import java.io.File;

import com.danger.dy.common.lang.utils.Lang;
import lombok.Getter;
import lombok.Setter;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpStatusCodeException;
import org.springframework.web.client.RestTemplate;

/**
 * rest client
 */
public final class RestClient {

    private RestClient() {
    }

    public static final int CODE_ERROR = 999;
    public static final int HTTP_OK_200 = 200;
    public static final int HTTP_OK_299 = 300;

    /**
     * error
     */
    public static class RestException extends RuntimeException {
        @Getter
        @Setter
        private int code;

        @Getter
        @Setter
        private String restMessage;

        public RestException(int code, String msg) {
            super(code + ": " + msg);
            this.code = code;
            this.restMessage = msg;
        }

        public RestException(int code, String msg, Throwable cause) {
            super(code + ": " + msg, cause);
            this.code = code;
            this.restMessage = msg;
        }
    }

    /**
     * @param responseEntity .
     * @return .
     */
    private static String processResult(ResponseEntity<String> responseEntity) {
        if (responseEntity.getStatusCodeValue() >= HTTP_OK_200 && responseEntity.getStatusCodeValue() <= HTTP_OK_299) {
            return responseEntity.getBody();
        }
        throw new RestException(responseEntity.getStatusCodeValue(), responseEntity.hasBody()
                ? responseEntity.getBody() : "request fail");
    }

    /**
     * @param url .
     * @return .
     */
    public static String get(String url) {
        RestTemplate restTemplate = new RestTemplate();
        try {
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(url, String.class);
            return processResult(responseEntity);
        } catch (Exception e) {
            if (e instanceof RestException) {
                throw e;
            } else if (e instanceof HttpStatusCodeException) {
                throw new RestException(((HttpStatusCodeException) e).getStatusCode().value(), e.getMessage(), e);
            } else {
                throw new RestException(CODE_ERROR, e.getMessage(), e);
            }
        }
    }

    /**
     * .
     *
     * @param cookie .
     * @param url    .
     * @param json   .
     * @return .
     */
    public static String postJson(String cookie, String url, String json) {
        HttpHeaders headers = new HttpHeaders();
        if (Lang.isNotEmpty(cookie)) {
            headers.add("Cookie", cookie);
        }
        headers.setContentType(MediaType.APPLICATION_JSON_UTF8);

        HttpEntity<String> request = new HttpEntity<>(json, headers);

        RestTemplate restTemplate = new RestTemplate();
        try {
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(url, request, String.class);
            return processResult(responseEntity);
        } catch (Exception e) {
            if (e instanceof RestException) {
                throw e;
            } else if (e instanceof HttpStatusCodeException) {
                throw new RestException(((HttpStatusCodeException) e).getStatusCode().value(), e.getMessage(), e);
            } else {
                throw new RestException(CODE_ERROR, e.getMessage(), e);
            }
        }
    }

    public static void download(String url, File outFile) {
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<byte[]> responseEntity = restTemplate.getForEntity(url, byte[].class);
        System.out.println(responseEntity.getStatusCode());
        byte[] bytes = responseEntity.getBody();
        Lang.filePutContent(outFile.getAbsolutePath(), bytes);
    }
}
